home *** CD-ROM | disk | FTP | other *** search
- #include "IPServer.H"
- #include "Internet.H"
- #include "Util.H"
-
-
- static VARTYPE rgI4[] = { VT_I4 };
-
- typedef enum {
- InternetEvent_Progress = 0,
- InternetEvent_ReadyStateChange = 1
- } INTERNETEVENTS;
-
- static EVENTINFO rgEvents [] = {
- { DISPID_PROGRESS, 1, rgI4 }, // (long percentDone)
- { DISPID_READYSTATECHANGE, 1, rgI4 }, // (OLE_READYSTATE newState)
- };
-
-
- // local class for doing async monitoring. It's not really all that
- // general purpose, but it does the job...
-
-
- class CDownloadSink : public IBindStatusCallback
- {
- public:
- CDownloadSink(IUnknown *punkOuter,CInternetControl *,DISPID );
- ~CDownloadSink();
-
- STDMETHOD(QueryInterface)(REFIID riid, void **ppvObjOut);
- STDMETHOD_(ULONG, AddRef)();
- STDMETHOD_(ULONG, Release)();
-
- STDMETHOD(GetBindInfo)(
- DWORD * grfBINDF,
- BINDINFO *pbindinfo);
-
- STDMETHOD(OnStartBinding)(
- IBinding *pib);
-
- STDMETHOD(GetPriority)(
- LONG *pnPriority);
-
- STDMETHOD(OnProgress)(
- ULONG ulProgress,
- ULONG ulProgressMax,
- ULONG ulStatusCode,
- LPCWSTR pwzStatusText);
-
- STDMETHOD(OnDataAvailable )(
- DWORD grfBSCF,
- DWORD dwSize,
- FORMATETC *pfmtetc,
- REFIID riid,
- IUnknown *punk);
-
- STDMETHOD(OnLowResource)(
- DWORD reserved);
-
- STDMETHOD(OnStopBinding)(
- HRESULT hrError);
-
- CDownloadSink * Next() { return(m_next); }
- void Next(CDownloadSink *n) { m_next = n; }
-
- DISPID DispId() { return(m_propId); }
- IBinding * Binding() { return(m_binding); }
-
- private:
-
- CDownloadSink * m_next;
- CInternetControl * m_control;
- DISPID m_propId;
- IBinding * m_binding;
- DWORD m_ref;
-
- };
-
-
- CDownloadSink::CDownloadSink
- (
- IUnknown * punkOuter,
- CInternetControl * control,
- DISPID propId
- )
- {
- // CHECK_POINTER(control);
-
- m_control = control;
- m_control->AddRef();
-
- m_propId = propId;
- m_next = 0;
- m_binding = 0;
- m_ref = 0;
- }
-
- CDownloadSink::~CDownloadSink()
- {
- if( m_control )
- m_control->Release();
- if( m_binding )
- m_binding->Release();
- }
-
- STDMETHODIMP
- CDownloadSink::QueryInterface(const GUID &iid,void **ppv )
- {
- if( IsEqualGUID(iid,IID_IUnknown) || IsEqualGUID(iid,IID_IBindStatusCallback) )
- {
- *ppv = this;
- AddRef();
- return(NOERROR);
- }
- return( E_NOINTERFACE );
- }
-
- STDMETHODIMP_(ULONG)
- CDownloadSink::AddRef()
- {
- return(++m_ref);
- }
-
- STDMETHODIMP_(ULONG)
- CDownloadSink::Release()
- {
- if(!--m_ref)
- {
- delete this;
- return(0);
- }
- return( m_ref );
- }
-
-
- STDMETHODIMP
- CDownloadSink::GetBindInfo( DWORD *grfBINDF, BINDINFO *pbindInfo)
- {
- *grfBINDF = BINDF_ASYNCHRONOUS;
- pbindInfo->szExtraInfo = 0;
- return(NOERROR);
- }
-
-
- STDMETHODIMP
- CDownloadSink::OnStartBinding(IBinding *pib)
- {
- m_binding = pib;
- pib->AddRef();
- return(NOERROR);
- }
-
-
- STDMETHODIMP
- CDownloadSink::GetPriority( LONG *pnPriority)
- {
- return(E_NOTIMPL);
- }
-
- STDMETHODIMP
- CDownloadSink::OnProgress
- (
- ULONG ulProgress,
- ULONG ulProgressMax,
- ULONG ulStatusCode,
- LPCWSTR pwzStatusText
- )
- {
- return(m_control->OnProgress(m_propId,ulProgress,
- ulProgressMax,ulStatusCode,pwzStatusText) );
- }
-
- STDMETHODIMP
- CDownloadSink::OnDataAvailable
- (
- DWORD grfBSCF,
- DWORD dwSize,
- FORMATETC * pFmtetc,
- REFIID iid,
- IUnknown * punk
- )
- {
- return(m_control->OnData(m_propId,grfBSCF,(IStream *)punk, dwSize ));
- }
-
- STDMETHODIMP
- CDownloadSink::OnLowResource( DWORD reserved)
- {
- m_binding->Abort();
- return(S_OK);
- }
-
- STDMETHODIMP
- CDownloadSink::OnStopBinding(HRESULT hrError)
- {
- m_binding->Release();
- m_binding = 0;
- m_control->Release();
- m_control = 0;
-
- return(NOERROR);
- }
-
-
-
- //------------------------------------------------------
- //
- // class CInternetControl
- //
- //
- CInternetControl::CInternetControl
- (
- IUnknown * pUnkOuter,
- int iPrimaryDispatch,
- void * pMainInterface
- )
- : COleControl(pUnkOuter,iPrimaryDispatch,pMainInterface)
- {
- m_downloads = 0;
- m_host = 0;
- m_readyState = READYSTATE_LOADING;
- }
-
- CInternetControl::~CInternetControl()
- {
- if( m_downloads )
- {
- CDownloadSink * next;
- do
- {
- next = m_downloads->Next();
- IBinding * binding = m_downloads->Binding();
- if( binding )
- binding->Abort();
- m_downloads->Release();
-
- } while ( (m_downloads = next) != 0 );
- }
-
- if( m_host )
- m_host->Release();
- }
-
-
- HRESULT CInternetControl::InternalQueryInterface
- (
- REFIID riid,
- void **ppvObjOut
- )
- {
- IUnknown *pUnk;
-
- *ppvObjOut = NULL;
-
- if (DO_GUIDS_MATCH(riid, IID_IServiceProvider)) {
- pUnk = (IUnknown *)(IServiceProvider *)this;
- } else{
- return COleControl::InternalQueryInterface(riid, ppvObjOut);
- }
-
- pUnk->AddRef();
- *ppvObjOut = (void *)pUnk;
- return S_OK;
- }
-
- STDMETHODIMP
- CInternetControl::QueryService(REFGUID guidService,
- REFIID riid, void **ppvObject)
- {
- HRESULT hr;
-
- IServiceProvider * clientsProvider;
-
- hr = m_pClientSite->QueryInterface(IID_IServiceProvider,
- (void**)&clientsProvider );
-
- if( SUCCEEDED(hr) )
- {
- hr = clientsProvider->QueryService(guidService,
- riid,ppvObject);
- clientsProvider->Release();
- }
-
- return(hr);
- }
-
-
- HRESULT
- CInternetControl::GetBindHost(IBindHost ** pHost )
- {
- HRESULT hr;
- if( !m_host )
- hr = GetBindHost();
- else
- hr = NOERROR;
- *pHost = m_host;
- return(hr);
- }
-
- HRESULT
- CInternetControl::GetBindHost()
- {
- if( m_host )
- return(NOERROR);
-
- IServiceProvider * serviceProvider = 0;
-
- HRESULT hr = m_pClientSite->QueryInterface
- (
- IID_IServiceProvider,
- (void**)&serviceProvider
- );
-
- if( SUCCEEDED(hr) )
- hr = serviceProvider->QueryService( SID_BindHost, IID_IBindHost,
- (void**)&m_host );
- else
- hr = E_FAIL; // C_E_UNKNOWNSERVICE;
-
- return(hr);
- }
-
- HRESULT CInternetControl::GetAMoniker( LPOLESTR url, IMoniker ** ppmkr )
- {
- HRESULT hr = GetBindHost();
-
- if( SUCCEEDED(hr) )
- hr = m_host->ParseDisplayName(url,ppmkr);
-
- if( FAILED(hr) )
- // FUTURE: This really should be a call to MkParseDisplayNameEx!!!
- hr = ::CreateURLMoniker(0,url,ppmkr);
-
- return( hr );
- }
-
-
- HRESULT CInternetControl::SetupDownload( IMoniker * moniker, DISPID propId )
- {
- HRESULT hr = GetBindHost();
-
- IBindCtx * pBindCtx = 0;
-
- if( SUCCEEDED(hr) )
- hr = m_host->GetBindCtx(0,&pBindCtx);
-
- if( FAILED(hr) )
- hr = ::CreateBindCtx(0,&pBindCtx);
-
- CDownloadSink * sink = 0;
-
- if( SUCCEEDED(hr) )
- {
- sink = new CDownloadSink(0,this,propId);
- if( sink )
- sink->AddRef();
- }
-
- if( SUCCEEDED(hr) && !sink )
- hr = E_OUTOFMEMORY;
-
- if( SUCCEEDED(hr) )
- {
- // FUTURE: This should be a call to RegisterBindStatusCallback!!
-
- hr = pBindCtx->RegisterObjectParam(OLESTR("BindStatusCallback"), sink );
- }
-
- IStream * strm = 0;
-
- if( SUCCEEDED(hr) )
- hr = moniker->BindToStorage( pBindCtx, 0, IID_IStream, (void**)&strm );
-
- if( strm )
- strm->Release();
-
- if( pBindCtx )
- pBindCtx->Release();
-
- if( FAILED(hr) && sink )
- sink->Release();
-
- if( SUCCEEDED(hr) )
- {
- if( m_downloads )
- m_downloads->Next(sink);
- m_downloads = sink;
- }
-
- return(hr);
-
- }
-
- HRESULT CInternetControl::SetupDownload( LPOLESTR url, DISPID propId )
- {
- CHECK_POINTER(url);
-
- IMoniker * pmkr;
-
- HRESULT hr = GetAMoniker( url, &pmkr );
-
- if( SUCCEEDED(hr) )
- return( SetupDownload(pmkr,propId) );
-
- return(hr);
-
- }
-
- HRESULT CInternetControl::SetupDownload( IStream * propStream, DISPID propId )
- {
- CHECK_POINTER(propStream);
-
- IMoniker * pmkr;
-
- HRESULT hr = ::OleLoadFromStream(propStream,IID_IMoniker,(void**)&pmkr);
-
- if( SUCCEEDED(hr) )
- return( SetupDownload(pmkr,propId) );
-
- return(hr);
- }
-
-
- HRESULT CInternetControl::OnData( DISPID, DWORD,IStream *, DWORD)
- {
- return(NOERROR);
- }
-
- HRESULT CInternetControl::OnProgress( DISPID, ULONG progress, ULONG themax, ULONG, LPCWSTR)
- {
- return(NOERROR);
- }
-
- HRESULT CInternetControl::GetBinding(DISPID dispId,IBinding** ppBinding)
- {
- CHECK_POINTER(ppBinding);
-
- CDownloadSink * sink = m_downloads;
-
- while(sink)
- {
- if( sink->DispId() == dispId )
- {
- if( (*ppBinding = sink->Binding()) == 0 )
- return( E_PENDING );
- return(S_OK);
- }
- sink = sink->Next();
- }
-
- return(E_FAIL);
- }
-
-
- HRESULT CInternetControl::FireReadyStateChange( long newState )
- {
- FireEvent( &::rgEvents[InternetEvent_ReadyStateChange], m_readyState = newState );
- return(S_OK);
- }
-
- HRESULT CInternetControl::FireProgress( ULONG dwAmount )
- {
- FireEvent( &::rgEvents[InternetEvent_Progress], dwAmount );
- return(S_OK);
- }
-